package com.sansecy.video.player;

import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.graphics.SurfaceTexture;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
import android.view.Gravity;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.TextureView;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ProgressBar;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.FragmentActivity;

import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.ui.PlayerView;
import com.google.android.exoplayer2.util.MimeTypes;
import com.sansecy.base.ScreenUtils;
import com.sansecy.base.file.FileUtilsKt;
import com.sansecy.base.file.OnFileClickListener;
import com.sansecy.base.fragment.BaseDialogFragment;
import com.sansecy.video.GestureController;
import com.sansecy.video.R;
import com.sansecy.video.TrackSelectionDialog;
import com.sansecy.video.VolumeBrightnessController;
import com.sansecy.video.player.ui.LockView;

import org.jetbrains.annotations.NotNull;

import java.io.File;
import java.lang.reflect.Field;

public class SimpleVideoView extends FrameLayout {

    private VideoTextureView videoTextureView;
    private IPlayer player;
    private int mVideoWidth;
    private int mVideoHeight;
    private ProgressBar mProgressBar;
    private MediaController mMediaController;
    private GestureController mGestureController;
    private int mTouchSlop;
    private long mSeekPosition = -1;
    private PlayerView mPlayerView;
    private LockView mLockView;

    public SimpleVideoView(@NonNull Context context) {
        super(context);
        createView(context, null);
//        setupListener();
    }

    public SimpleVideoView(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        createView(context, attrs);
//        setupListener();
    }

    private void createView(@NotNull Context context, @Nullable AttributeSet attrs) {
        LayoutParams layoutParams = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        layoutParams.gravity = Gravity.CENTER;
        mPlayerView = new PlayerView(context, attrs);
        mPlayerView.setUseController(false);
        mPlayerView.setControllerAutoShow(false);
        addView(mPlayerView, layoutParams);
        addView(videoTextureView = new VideoTextureView(context, attrs), layoutParams);
        mProgressBar = new ProgressBar(getContext());
        LayoutParams params = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        params.gravity = Gravity.CENTER;
        addView(mProgressBar, params);
        mGestureController = new GestureController(getContext());

        addView(mGestureController);
//
        mMediaController = new MediaController(getContext());
        mMediaController.hide();
        addView(mMediaController);
        mLockView = new LockView(getContext());
        mLockView.hide();
        mLockView.setLock(false);
        mLockView.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                mLockView.setLock(!mLockView.isLock());
                mGestureController.setEnabled(!mLockView.isLock());
                if (mLockView.isLock()) {
                    mMediaController.hide();
                }
            }
        });
        LayoutParams lockLP = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        lockLP.gravity = Gravity.CENTER_VERTICAL;
        addView(mLockView, lockLP);

        int dp16 = ScreenUtils.dpToPx(getContext(), 16);
        if (mMediaController != null) {
            mMediaController.setPadding(dp16, 0, dp16, 0);
        }
        mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
        mGestureController.setOnProgressChangeListener(new VolumeBrightnessController.OnProgressChangeListener() {
            @Override
            public void onProgressChange(int progress) {
                mSeekPosition = (int) (progress + player.getCurrentPosition());
                //fixme 不建议反着调用，由mGestureController的毁掉
                mGestureController.onProgressChange(player.getDuration(), mSeekPosition);
            }
        });
        mGestureController.setOnGestureListener(new GestureDetector.SimpleOnGestureListener() {
            @Override
            public boolean onDoubleTap(MotionEvent e) {
                if (player != null) {
                    if (player.isPlaying()) {
                        player.pause();
                    } else {
                        if (player.getCurrentPosition() >= player.getDuration()) {
                            player.seekTo(0);
                        }
                        player.start();
                    }
                    return true;
                }
                return super.onDoubleTap(e);
            }

            @Override
            public boolean onSingleTapConfirmed(MotionEvent e) {
                if (mLockView.isShowing()) {
                    mLockView.hide();
                } else {
                    mLockView.show();
                }
                if (!mMediaController.isShowing() && !mLockView.isLock()) {
                    mMediaController.show();
                } else {
                    mMediaController.hide();
                }
                return true;
            }

        });
        configMediaController();
    }

    private void configMediaController() {
        mMediaController.setOnNavigationOnClickListener(new MediaController.OnNavigationOnClickListener() {
            @Override
            public void onClick() {
                Activity activity = (Activity) getContext();
                activity.finish();
            }
        });
        mMediaController.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem item) {
                int itemId = item.getItemId();
                if (itemId == R.id.change_subtitle) {
                    try {
                        Class<?> name = Class.forName("com.sansecy.filemanager.FileManagerDialogFragment");
                        BaseDialogFragment dialogFragment = (BaseDialogFragment) name.newInstance();
                        dialogFragment.setOnFileClickListener(new OnFileClickListener() {
                            @Override
                            public boolean onFileClick(File file) {
                                String path = file.getPath();
                                if (path.endsWith("ass")) {
                                    player.setSubtitle(path, MimeTypes.TEXT_SSA);
                                    dialogFragment.dismiss();
                                    return true;
                                } else if (path.endsWith("srt")) {
                                    player.setSubtitle(path, MimeTypes.APPLICATION_SUBRIP);
                                    dialogFragment.dismiss();
                                    return true;
                                }
                                return false;
                            }
                        });
                        dialogFragment.show(((FragmentActivity) getContext()).getSupportFragmentManager(), "");
                    } catch (ClassNotFoundException | IllegalAccessException | InstantiationException e) {
                        e.printStackTrace();
                    }
                } else if (itemId == R.id.change_tracker) {
                    ExoPlayer exoplayer = (ExoPlayer) player.getIPlayer();
                    try {
                        Field mTrackSelector = ExoPlayer.class.getDeclaredField("mTrackSelector");
                        mTrackSelector.setAccessible(true);
                        Object o = mTrackSelector.get(exoplayer);
                        TrackSelectionDialog forTrackSelector = TrackSelectionDialog.createForTrackSelector((DefaultTrackSelector) o, new DialogInterface.OnDismissListener() {
                            @Override
                            public void onDismiss(DialogInterface dialog) {
                                Log.d(TAG, "onDismiss() called with: dialog = [" + dialog + "]");
                            }
                        });
                        FragmentActivity activity = (FragmentActivity) getContext();
                        forTrackSelector.show(activity.getSupportFragmentManager(), "");
                    } catch (NoSuchFieldException | IllegalAccessException e) {
                        e.printStackTrace();
                    }

                }
                return false;
            }
        });
    }

    public void setTitle(String title) {
        mMediaController.setTitle(title);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            if (mLockView.isLock()) {
                if (mLockView.isShowing()) {
                    mLockView.hide();
                } else {
                    mLockView.show();
                }
            }
        }
        boolean result = mGestureController.onTouchEvent(event);
        // 处理横行滑动后跳转到视频的位置
        switch (event.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_UP:
                if (player != null && mSeekPosition > -1) {
                    player.seekTo(mSeekPosition);
                    mSeekPosition = -1;
                }
                break;
        }
        if (result) {
            return true;
        }
        return super.onTouchEvent(event);
    }

    private void setupListener() {
        videoTextureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
            @Override
            public void onSurfaceTextureAvailable(@NonNull SurfaceTexture surface, int width, int height) {
                Log.d(TAG, "onSurfaceTextureAvailable() called with: surface = [" + surface + "], width = [" + width + "], height = [" + height + "]");
                if (player != null) {
                    player.setDisplay(new Surface(surface));
                }
            }

            @Override
            public void onSurfaceTextureSizeChanged(@NonNull SurfaceTexture surface, int width, int height) {
                Log.d(TAG, "onSurfaceTextureSizeChanged() called with: surface = [" + surface + "], width = [" + width + "], height = [" + height + "]");
            }

            @Override
            public boolean onSurfaceTextureDestroyed(@NonNull SurfaceTexture surface) {
                return false;
            }

            @Override
            public void onSurfaceTextureUpdated(@NonNull SurfaceTexture surface) {

            }
        });
    }

    @Override
    protected void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
//        videoTextureView.setVideoWidthHeight(mVideoWidth, mVideoHeight);
    }

    public void setVideoWidthHeight(int videoWidth, int videoHeight) {
        mVideoWidth = videoWidth;
        mVideoHeight = videoHeight;
//        videoTextureView.setVideoWidthHeight(mVideoWidth, mVideoHeight);
    }

    private String uri;

    public void setUri(String uri) {
        this.uri = uri;
    }

    private static final String TAG = "VideoView-App";

    public void setPlayer(IPlayer player) {
        this.player = player;
        mPlayerView.setPlayer((Player) player.getPlayer());
        mMediaController.setMediaPlayer(player);
        player.setOnVideSizeChangeListener(new IPlayer.OnVideoSizeChangedListener() {
            @Override
            public void onVideoSizeChanged(int width, int height) {
                if (width > height) {
                    Activity context = (Activity) getContext();
                    context.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
                }
                setVideoWidthHeight(width, height);

            }
        });
        player.setOnBufferListener(new IPlayer.OnBufferListener() {
            @Override
            public void onBufferStart() {
                mProgressBar.setVisibility(View.VISIBLE);
                setControllerVisibility();
            }

            @Override
            public void onBufferEnd() {
                mProgressBar.setVisibility(View.GONE);
            }

            @Override
            public void onBufferUpdate(int percent) {

            }
        });

    }

    private void setControllerVisibility() {
        String mimeType = "";
        if (uri != null && uri.startsWith("http")) {
            mimeType = FileUtilsKt.getMimeType(uri);
        } else {
            mimeType = FileUtilsKt.getMimeType(new File(uri));
        }
        if (mimeType.contains("audio")) {
            mMediaController.show(0);
        } else {
            mMediaController.show();
        }
    }
}
